package com.example.lenovo.mywechat;

import android.content.Intent;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

import android.os.AsyncTask;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.example.lenovo.mywechat.homepage.Homepage;
import com.example.lenovo.mywechat.login.Login;
import com.example.lenovo.mywechat.server_config.ServerConfig;
import com.google.protobuf.ByteString;
import com.snow.proto.MyRequest;
import com.snow.proto.MyResponse;
import com.snow.proto.StreamRequest;
import com.snow.proto.StreamResponse;
import com.snow.proto.StudentProto;
import com.snow.proto.StudentRequest;
import com.snow.proto.StudentResponse;
import com.snow.proto.StudentResponseList;
import com.snow.proto.StudentServiceGrpc;

import java.time.LocalDateTime;
import java.util.Iterator;

import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.stub.StreamObserver;

public class MainActivity extends AppCompatActivity  implements View.OnClickListener {

    //以下成员变量可以删除，仅用于测试子线程通知主线程更新UI界面。
    private TextView mTvTest;
    private Button mBtnTest1;
    private Button mBtnTest2;
    private Button mBtnTest3;
    private Button mBtnTest4;
    private Button mBtnTest5;
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 100) {
                mTvTest.setText("由Handler发送消息");
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent intent = new Intent(this, Login.class);
        this.startActivity(intent);
        this.finish();



//        this.HandlerTest();//用于测试子线程通知主线程更新UI界面。

//        this.GrpcTest();//用于测试grpc安卓作为客户端，java作为服务端（grpc_MyWechatServer）。
    }

    public void GrpcTest(){
        //grpc测试(需要很长一段时间才能显示出来，因为最后主线程才会更新一次UI界面。)
        setContentView(R.layout.test);
        TextView textView = this.findViewById(R.id.textView);
        textView.setText("");
        ManagedChannel managedChannel = ManagedChannelBuilder.forAddress("10.1.88.215", 8899).usePlaintext(true).build();

        //同步、阻塞式：
        StudentServiceGrpc.StudentServiceBlockingStub blockingStub = StudentServiceGrpc.newBlockingStub(managedChannel);

        //异步：只要请求为流，那么就只能使用异步；请求不为流也可以使用异步。
        StudentServiceGrpc.StudentServiceStub stub = StudentServiceGrpc.newStub(managedChannel);

        textView.append("------------------请求非流，响应非流：-------------------------" + "\n");

        MyResponse myResponse = blockingStub.getRealNameByUsername(
                MyRequest.newBuilder().setUsername("zhangsan").build()
        );
        textView.append(myResponse.getRealname() + "\n");

        textView.append("------------------请求非流，响应为流：-------------------------" + "\n");

        Iterator<StudentResponse> iter = blockingStub.getStudentsByAge(
                StudentRequest.newBuilder().setAge(20).build()
        );
        while (iter.hasNext()){
            StudentResponse studentResponse = iter.next();
            textView.append(studentResponse.getName() + ","
                    + studentResponse.getAge() + ","
                    + studentResponse.getCity() + "\n"
            );
//            break;//客户端也可以选择不完全接收数据，但要等到服务端把数据全部传过来，否则服务端会报客户端强制关闭连接错误。
        }

        textView.append("------------------请求为流，响应非流，响应为集合：-------------------------" + "\n");

        //对服务端响应的发送来的集合进行处理
        StreamObserver<StudentResponseList> studentResponseListStreamObserver = new StreamObserver<StudentResponseList>() {
            @RequiresApi(api = Build.VERSION_CODES.N)
            @Override
            public void onNext(StudentResponseList value) {
                value.getStudentResponseList().forEach(studentResponse -> {
                    textView.append(studentResponse.getName() + "\n");
                    textView.append(studentResponse.getAge() + "\n");
                    textView.append(studentResponse.getCity() + "\n");
                    textView.append("*************" + "\n");
                });
            }

            @Override
            public void onError(Throwable t) {
                textView.append(t.getMessage() + "\n");
            }

            @Override
            public void onCompleted() {
                textView.append("completed!" + "\n");
            }
        };
        StreamObserver<StudentRequest> studentRequestStreamObserver = stub.getStudentsWrapperByAges(studentResponseListStreamObserver);
        //流式的请求构建：
        studentRequestStreamObserver.onNext(StudentRequest.newBuilder().setAge(20).build());
        studentRequestStreamObserver.onNext(StudentRequest.newBuilder().setAge(30).build());
//        try {
//            Thread.sleep(1000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        studentRequestStreamObserver.onNext(StudentRequest.newBuilder().setAge(40).build());
        studentRequestStreamObserver.onNext(StudentRequest.newBuilder().setAge(50).build());

        studentRequestStreamObserver.onCompleted();

        textView.append("------------------请求为流，响应为流：-------------------------" + "\n");

        //对服务端响应的发送来的每一块流进行处理
        StreamObserver<StreamRequest> requestStreamObserver = stub.biTalk(new StreamObserver<StreamResponse>() {
            @Override
            public void onNext(StreamResponse value) {
                textView.append(value.getResponseInfo() + "\n");
            }

            @Override
            public void onError(Throwable t) {
                textView.append(t.getMessage() + "\n");
            }

            @Override
            public void onCompleted() {
                textView.append("onCompleted" + "\n");
            }
        });
        //流式的请求构建：
        for (int i = 0; i < 10; i++){
            requestStreamObserver.onNext(
                    StreamRequest.newBuilder().setRequestInfo(
                            System.currentTimeMillis() + "\n"
                    ).build()
            );
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        requestStreamObserver.onCompleted();//如果请求是流则一定要调用onCompleted，否则服务端会报客户端强制关闭连接错误。

        textView.append("-------------------最底部------------------------" + "\n");
        try {
            Thread.sleep(3000);//此句是因为使用了异步，要等待一段时间才能出结果。
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        managedChannel.shutdown();//防止强制关闭客户端造成服务端报错。
    }

    /**
     * 用于测试子线程通知主线程更新UI界面。
     */
    public void HandlerTest(){
        setContentView(R.layout.thread_test);

        mTvTest = (TextView) findViewById(R.id.tv_test);
        mBtnTest1 = (Button) findViewById(R.id.btn_test1);
        mBtnTest2 = (Button) findViewById(R.id.btn_test2);
        mBtnTest3 = (Button) findViewById(R.id.btn_test3);
        mBtnTest4 = (Button) findViewById(R.id.btn_test4);
        mBtnTest5 = (Button) findViewById(R.id.btn_test5);
        mBtnTest1.setOnClickListener(this);
        mBtnTest2.setOnClickListener(this);
        mBtnTest2.setOnClickListener(this);
        mBtnTest3.setOnClickListener(this);
        mBtnTest4.setOnClickListener(this);
        mBtnTest5.setOnClickListener(this);

//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                try {
//                    Thread.sleep(200);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//                mTvTest.setText("子线程可以更新UI");
//            }
//        }).start();
    }

    /**
     * 用于测试子线程通知主线程更新UI界面。
     */
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_test1:
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        mTvTest.setText("子线程真的可以更新UI吗？");
                    }
                }).start();
                break;
            case R.id.btn_test2:   //通过发送消息
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        mHandler.sendEmptyMessage(100);
                    }
                }).start();
                break;
            case R.id.btn_test3:  //通过Handler.post方法
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                mTvTest.setText("handler.post");
                            }
                        });
                    }
                }).start();
                break;
            case R.id.btn_test4:  //通过 view.post方法
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        mTvTest.post(new Runnable() {
                            @Override
                            public void run() {
                                mTvTest.setText("view.post");
                            }
                        });
                    }
                }).start();
                break;
            case R.id.btn_test5:  //通过 activity 的 runOnUiThread方法
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        MainActivity.this.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                mTvTest.setText("runOnUIThread");
                            }
                        });
                    }
                }).start();
                break;
            default:
                break;
        }
    }
}
